//`define AUTO_RESET_PHY // PHY出错时是否复位
//`define ENABLE_RESET_PLL // 是否可通过网络复位PLL

`timescale    1ns/100ps
module sys_other
(
    input       wire            sclkin          , //25m
    output      wire            resetb          ,
    output      wire            sclk            , //125m
    output      wire            sdram_clk     , //125M
    output      wire            sclk_shift      ,
    
    input       wire            rec_flag        ,
    input       wire            rec_error_sync  ,
    
    input       wire            input_active    ,
    input       wire            comm_en         ,
    
    input       wire            reconfig_pll_en ,
    
    output      wire            led_g           ,
    
    output      wire    [ 3:0]  pll_reset_cnt_sync  ,
    output      wire    [20:0]  time_us         ,
    output      wire    [20:0]  sync_us
    
);

//****************************************************************
//        内部信号
//****************************************************************
reg  [5:0]  reset_init = 6'b0 /* synthesis syn_preserve = 1*/;
wire        init_pll;

reg  [7:0]  reset_pll;
wire        pll_lock;


wire        inner_led_g;
//**************************************************************
//        时钟复位管理单元
//**************************************************************
//上电后resetb保持0.1秒低电平
sys_reset_ctrl sys_reset_ctrl(
    .sclkin(sclkin),
    .resetb(resetb)
    );

assign init_pll = reset_init[5];
always @ (posedge sclkin)
    if (!init_pll)
        reset_init <= reset_init + 1'b1;

`ifdef ALTERA
sys_pll_c2_no_shift pll (
    .inclk0 ( sclkin ),
    .c0     ( sclk ),
    .c1     ( sdram_clk ),
    .c2     ( sclk_shift),
    .areset ( !init_pll | reset_pll[0]),
    .pfdena ( init_pll ),
    .locked ( pll_lock )
);
`else

sys_pll pll (
    .inclk0 ( sclkin ),
    .c0     ( sclk ),
    .c1     ( /*sdram_clk*/ ),
    .c2     ( sclk_shift ),
    .areset ( !init_pll | reset_pll[0]),
    .pfdena ( init_pll ),
    .locked ( pll_lock )
);
assign sdram_clk = ~sclk;
`endif


// time_xx
sys_timer sys_timer(
    .resetb(resetb),
    .sclk(sclk),

    .time_us    (   time_us ),
    .sync_us    (   sync_us )
    );



//led状态指示
Led_Ctrl_SV2    Led_Ctrl_SV2(
    .resetb(resetb),
    .sclk(sclk),

    .time_ms(time_us[10]),  //time_1ms
    .time_250ms(time_us[18]), //time_250ms

    .G_black(1'b0),
    .G_flash(rec_flag),

    .R_light(),
    .R_flash(rec_error_sync),

    .G_flash_1st(1'd1),
    .R_flash_1st(1'd0),

    .tx_err_en(1'b0),

    .nG_led(inner_led_g),
    .nR_led()
    );

//***********LED灯和按键接口选通*************
ledG_press_IO ledG_press_IO(
    .sclk(sclk),
    .input_active(input_active && comm_en),
    .detect_sync(sync_us[14]), //time_15ms_sync
    .sample_sync(sync_us[10]),//time_1ms_sync

    .inner_led_g(inner_led_g),
    .led_g(led_g)
    );

//**************************************************************
//        PLL状态监测
//**************************************************************
reg  [3:0]  pll_reset_cnt;
reg  [3:0]  pll_reset_cnt_sync0;
reg  [3:0]  pll_reset_cnt_sync1;

reg  [5:0]  reconfig_pll_pulse;
reg  [3:0]  reconfig_pll_sync;


always @(posedge sclk) begin
    if (reconfig_pll_en)
        reconfig_pll_pulse <= 6'b111111;
    else
        reconfig_pll_pulse <= reconfig_pll_pulse >> 1'b1;
end

always @(posedge sclkin or negedge resetb) begin
    if (~resetb)
        reconfig_pll_sync <= 1'b0;
    else
        reconfig_pll_sync <= {reconfig_pll_sync[2:0], reconfig_pll_pulse[0]};
end

`ifdef ENABLE_RESET_PLL
// reset_pll
always @(posedge sclkin or negedge resetb) begin
    if (~resetb)
        reset_pll <= 1'b0;
    else if (reconfig_pll_sync[3:2] == 2'b01)
        reset_pll <= 8'hff;
    else
        reset_pll <= reset_pll >> 1'b1;
end
`else
always @(*) reset_pll = 1'b0;
`endif

// pll_reset_cnt
always @(posedge sclkin or negedge resetb) begin
    if (~resetb)
        pll_reset_cnt <= 1'b0;
    else if (reconfig_pll_sync[3:2] == 2'b01 && pll_reset_cnt != 4'hf)
        pll_reset_cnt <= pll_reset_cnt + 1'b1;
end

always @(posedge sclk) begin
    pll_reset_cnt_sync0 <= pll_reset_cnt;
    pll_reset_cnt_sync1 <= pll_reset_cnt_sync0;
end

assign pll_reset_cnt_sync = pll_reset_cnt_sync1;

endmodule
`default_nettype wire